<?php

class Socket extends AppLog
{
	var $host = "";
	var $port = 0;
	var $connServer = 1;
	var $connServerError = 1;
	var $checkRead = 0;
	var $timesRead = 10;
	var $countRead = 10;
	var $countBuffer = 20;
	var $timesBuffer = 20;
	var $errString = "";
	var $errNumber = 0;
	var $sockServer;
	var $timeStart = 0;
	var $timeEnd = 0;
	var $timeDiff = 0;
	var $vars = array("rxEOF" => 0);
	var $bufCompleto = "";
	var $bufParziale = "";
	var $bufPos = 0;
	
	function __construct($host, $port)
	{
		$this->__open();
		$this->host = $host;
		$this->port = $port;
		$this->connect();
	}

	function __destruct() 
	{
		//$this->dbgWrite("Socket QUIT ");
		fwrite($this->sockServer, "QUIT\n", strlen( "QUIT\n" ));
	}

	function close()
	{
		fclose($this->sockServer);
		$this->connServer = 1;
		$this->connServerError = 0;
	}
	
	function connect()
	{
		if ( $this->connServer )
		{
			$this->sockServer = fsockopen($this->host, $this->port, $this->errString, $this->errNumber, 5);
			if ( $this->errNumber != 0 )
			{
				$this->dbgWrite("ERROR : ".$this->errString);
				$this->connServer = 1;
				$this->connServerError = 1;
				return true;
			}
			$this->connServer = 0;
			$this->connServerError = 0;
			stream_set_blocking($this->sockServer, FALSE);
			//$this->dbgWrite("Socket Connect Host=".$this->host." - Port=".$this->port);
		}
		return false;
	}

	function __microtimeFloat()
	{
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}

	function timeOut( $type = false)
	{
		if ( $type )
		{
			$this->timeStart = $this->__microtimeFloat();
			//$this->dbgWrite("Read Socket TimeOut Start : $this->timeStart");
		}
		else
		{
			$this->timeEnd = $this->__microtimeFloat();
			$this->timeDiff = $this->timeEnd - $this->timeStart;
			//$this->dbgWrite("Read Socket TimeOut : $this->timeEnd - $this->timeStart = $this->timeDiff");
			return $this->timeDiff >= 10;
		}
	}
	
	function rxEof()
	{
		return $this->vars["rxEOF"];
	}

	function _rxData( &$bufDati )
	{
		//$bufParziale = "";
		$bufDati = '';
		$buffer = '';
		$this->bufPos = 0;
		$exit = 1;
		$this->timeOut( true );
		$cnt = 0;
		$this->dbgWrite("Read Socket bufParziale : ".$this->bufParziale);
		do
		{
			if ( ($buffer = fread($this->sockServer, 16384)) === FALSE )
			{
				$this->dbgWrite("ERROR : No Connect");
				$this->connServer = 1;
				$this->connServerError = 1;
				$this->vars["rxEOF"] = 0;
				return 0;
			}
			if ( $this->timeOut() )
			{
				$this->dbgWrite("ERROR : No Connect");
				$this->connServer = 1;
				$this->connServerError = 1;
				$this->vars["rxEOF"] = 0;
				return 0;
			}
			$this->bufParziale.= $buffer;
			$this->bufPos = strpos($this->bufParziale, "\n.EOF");
			if ( $this->bufPos === false)
				$this->bufPos = strpos($this->bufParziale, ".EOF");
			$this->dbgWrite("Read Socket Buffer : ".$bufDati." - ".$this->bufPos." - ".$this->bufParziale);
			if ( $this->bufPos === false ) 
			{
				$bufDati.= $this->bufParziale;
				$this->bufParziale = "";
			}
			else
			{
				//$this->dbgWrite("Read Socket Buffer : $bufPos - ".strlen($buffer));
				$exit = 0;
				$this->vars["rxEOF"] = 0;
				$bufDati.= substr($this->bufParziale, 0, $this->bufPos);
				if ( strlen($this->bufParziale) > 4 )
					$this->bufParziale = substr($this->bufParziale, $this->bufPos + 5);
				else
					$this->bufParziale = substr($this->bufParziale, $this->bufPos + 4);
				//$bufParziale = preg_replace("/\.EOF$/","",$buffer);
			}
			$this->dbgWrite("Read Socket BufferCompleto : ".$bufDati." - ".$this->bufParziale);
			$buffer = '';
		}
		while( $exit );
		
		return 1;
	}

	function rxData()
	{
		//$bufParziale = "";
		$this->bufCompleto = "";
		$buffer = "";
		$this->bufPos = 0;
		$exit = 1;
		$this->timeOut( true );
		$cnt = 0;
		//$this->dbgWrite("Read Socket bufParziale : ".$this->bufParziale);
		do
		{
			if ( ($buffer = fread($this->sockServer, 16384)) === FALSE )
			{
				$this->dbgWrite("ERROR : No Connect");
				$this->connServer = 1;
				$this->connServerError = 1;
				$this->vars["rxEOF"] = 0;
				return 0;
			}
			if ( $this->timeOut() )
			{
				$this->dbgWrite("ERROR : No Connect");
				$this->connServer = 1;
				$this->connServerError = 1;
				$this->vars["rxEOF"] = 0;
				return 0;
			}
			$this->bufParziale.= $buffer;
			$this->bufPos = strpos($this->bufParziale, "\n.EOF");
			if ( $this->bufPos === false)
				$this->bufPos = strpos($this->bufParziale, ".EOF");
			//$this->dbgWrite("Read Socket Buffer : ".$this->bufCompleto." - ".$this->bufPos." - ".$this->bufParziale);
			if ( $this->bufPos === false ) 
			{
				$this->bufCompleto.= $this->bufParziale;
				$this->bufParziale = "";
			}
			else
			{
				//$this->dbgWrite("Read Socket Buffer : $bufPos - ".strlen($buffer));
				$exit = 0;
				$this->vars["rxEOF"] = 0;
				$this->bufCompleto.= substr($this->bufParziale, 0, $this->bufPos);
				if ( strlen($this->bufParziale) > 4 )
					$this->bufParziale = substr($this->bufParziale, $this->bufPos + 5);
				else
					$this->bufParziale = substr($this->bufParziale, $this->bufPos + 4);
				//$bufParziale = preg_replace("/\.EOF$/","",$buffer);
			}
			//$this->dbgWrite("Read Socket BufferCompleto : ".$this->bufCompleto." - ".$this->bufParziale);
			$buffer = "";
			$cnt++;
			if ( strlen($this->bufCompleto) >= 16384 ) $exit = 0;
		}
		while( $exit );
		
	    //$this->dbgWrite("Read Socket BufferCompleto : ".$this->bufCompleto);
		return $this->bufCompleto;
	}

	/**
		
	 */

	function txData($str)
	{
		if ( fwrite($this->sockServer, $str, strlen( $str ) ) === FALSE )
		{
			//$this->dbgWrite("Error : txData");
			$this->errString = "Error : txData";
			return 1;
		}
		$this->vars["rxEOF"] = 1;
		return 0;
	}

	/**
		
	 */

	function txDataFile($path, $bLen)
	{
		$this->logWrite( "path $path" );
		$FL = fopen( $path, "rb");
		while ( ! feof( $FL ) )
		{
			$buf = fread($FL, $bLen);			
			//$this->logWrite( "send $buf" );
			//$this->logWrite( "send ".strlen($buf) );
			if ( $this->txData( $buf."\n" ) )
			{
				$this->logWrite("Socket error: ".$this->socket->errString);
				break;
			}
			while( $this->rxEof() && ! $this->connError() )
			{
				$response = $this->rxData();				
				//$this->logWrite( "response $response" );
				if ( preg_match("/^ERROR/i", $response) ) return $response;
			}
			if ( $this->connError() ) break;
		}
		fclose($FL);
		
		if ( $this->connError() ) return 'ERROR';
	}

	function connError()
	{
		return $this->connServerError;
	}
	
	function startRemoteRows($cmd)
	{
		$this->dbgWrite("startRemoteRows $cmd");
		if ( $cmd != "" )
		{
			if ( $this->txData("$cmd\n") ) return $this->errString;
		}
	}

	function endRemoteRows(&$result)
	{
		$response = "";
		$result = array();
		$this->vars["rxEOF"] = 1;
		while( $this->rxEof() && ! $this->connError() )
		{
			$response.= $this->rxData();
			if ( preg_match("/^ERROR/i", $response) ) return $response;
			while ( $end = strpos($response, "\n") )
			{
				$result[] = substr($response, 0, $end);
				$response = substr($response, $end + 1);
			}
		}
		if ( $response != "\n" && $response != "" ) $result[] = $response;
		return "";
	}
	
	function reqRemoteRows($cmd, &$result, $debug = false)
	{
		$response = "";
		$result = array();
		$this->dbgWrite("reqRemoteRows $cmd");
		if ( $debug ) return "OK";
		
		if ( $cmd != "" )
		{
			if ( $this->txData("$cmd\n") ) return $this->errString;
			
			while( $this->rxEof() && ! $this->connError() )
			{
				$response.= $this->rxData();
				
				if ( preg_match("/^ERROR/i", $response) ) return 'ERROR';
				while ( $end = strpos($response, "\n") )
				{
					//$this->dbgWrite("response $end = ".substr($response, 0, $end));
					$result[] = substr($response, 0, $end);
					$response = substr($response, $end + 1);
					if ( preg_match("/^ERROR/i", $response) ) return 'ERROR';
				}
				//usleep( 1000000 );
			}
			if ( $response != "\n" && $response != "" )
				$result[] = $response;
		}
		return "";
	}

	function reqRemoteResponse($cmd, $debug = false)
	{
		$response = "";

		$this->dbgWrite("reqRemoteResponse $cmd");
		if ( $debug ) return "OK";
		
		if ( $cmd != "" )
		{			
			if ( $this->txData("$cmd\n") ) return $this->errString;
		
			while( $this->rxEof() && ! $this->connError() )
			{
				$response.= $this->rxData();
			}
			//$this->dbgWrite("reqRemoteResponse $response");
		}
		
		return $response;
	}

	function readRemoteWriteFile($cmd, $fileName)
	{
		$response = "";
		
		if ( $cmd != "" )
		{
			if ( ! file_exists($fileName) )
			{
				$FL = fopen($fileName, "w");
				if ( $this->txData("$cmd\n") )
				{
					return $this->errString;
				}
				
				while( $this->rxEof() && ! $this->connError() )
				{
					fwrite( $FL,  $this->rxData() );
				}
				fclose($FL);
			}
		}
	}
}

?> 
